﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.Data.Linq;
using System.Data.Common;
using TSV.Library.Common;
using TSV.Models;
using Pagination;

namespace TSV.Models
{
    public class CategoryDao : BaseDao
    {
        public List<Category> GetList()
        {
            return dbContext.Categories.Where(c => c.ParentId == null).OrderBy(c => c.CategoryOrder).ToList<Category>();                        
        }

        public List<Category> GetAllCategories()
        {
            return dbContext.Categories.OrderBy(c => c.CategoryOrder).ToList<Category>();
        }

        public Promotion GetPromotionByID(int id)
        {
            return dbContext.Promotions.Where(q => q.ID == id && q.Active == true).FirstOrDefault();
        }

        public List<Province> GetListProvince()
        {
            return dbContext.Provinces.ToList();
        }

        public List<sp_GetProvinceListByCategoryResult> GetProvinceList(int category)
        {
            return dbContext.sp_GetProvinceListByCategory(category).ToList();
        }

        public List<District> GetDitrictList()
        {
            return dbContext.Districts.ToList();
        }

        public List<District> GetDitrictListByProvinceID(int province)
        {
            return dbContext.Districts.Where(q => q.ProvinceID == province).ToList();
        }

        public Category GetByID(int id)
        {
            return dbContext.Categories.Where(q => q.ID == id).FirstOrDefault();
        }

        public District GetDistrictByID(int id)
        {
            return dbContext.Districts.Where(q => q.ID == id).FirstOrDefault();
        }

        public Province GetProvinceByID(int id)
        {
            return dbContext.Provinces.Where(q => q.ID == id).FirstOrDefault();
        }

        public List<Category> GetParentList()
        {
            return dbContext.Categories.Where(c => !c.ParentId.HasValue).OrderBy(c=> c.CategoryOrder).ToList<Category>();
        }

        public List<Category> GetParentListExcludeItself(int id)
        {
            return dbContext.Categories.Where(c => !c.ParentId.HasValue && c.ID != id).OrderBy(c => c.CategoryOrder).ToList<Category>();
        }

        public List<Category> GetChildListByParentId(int parentId)
        {
            return dbContext.Categories.Where(c => c.ParentId == parentId).ToList<Category>();
        }

        /// <summary>
        /// Sort Product
        /// </summary>
        /// <param name="list"></param>
        /// <param name="sortColumn"></param>
        /// <param name="sortOrder"></param>
        /// <returns></returns>
        public List<Category> Sort(List<Category> list, string sortColumn, string sortOrder)
        {
            int order;

            if (sortOrder == "desc")
            {
                order = -1;
            }
            else
            {
                order = 1;
            }
            switch (sortColumn)
            {
                case "CategoryName":
                    list.Sort(
                         delegate(Category m1, Category m2)
                         { return m1.CategoryName.CompareTo(m2.CategoryName) * order; });
                    break;                                
            }

            return list;
        }

        public Message Insert(Category objUI)
        {
            Message msg = null;
            try
            {
                if (objUI != null)
                {
                    if (CheckParentCatIsUsing(objUI))
                    {
                        // Show success message
                        Category parent = GetByID(objUI.ParentId.Value);
                        msg = new Message(MessageConstants.E0044, MessageType.Error,"'" + parent.CategoryName + "'");
                    }
                    else
                    {
                        dbContext.Categories.InsertOnSubmit(objUI);
                        dbContext.SubmitChanges();

                        // Show success message
                        msg = new Message(MessageConstants.I0001, MessageType.Info, "Danh mục '" + objUI.CategoryName + "'", "thêm");
                    }
                }
            }
            catch (Exception)
            {
                // Show system error
                msg = new Message(MessageConstants.E0007, MessageType.Error);
            }
            return msg;
        }

        public Message Update(Category objUI)
        {
            Message msg = null;
            try
            {
                if (objUI != null)
                {
                    // Get current group in dbContext
                    Category objDb = GetByID(objUI.ID);

                    if (objDb != null)
                    {
                        //if (CheckParentCatIsUsing(objUI))
                        //{
                        //    // Show success message
                        //    Category parent = GetByID(objUI.ParentId.Value);
                        //    msg = new Message(MessageConstants.E0044, MessageType.Error, "'" + parent.CategoryName + "'");
                        //}
                        //else
                        //{
                            // Update info by objUI
                            objDb.Image = objUI.Image;
                            objDb.CategoryName = objUI.CategoryName;
                            objDb.Description = objUI.Description;
                            objDb.ParentId = objUI.ParentId;

                            // Submit changes to dbContext
                            dbContext.SubmitChanges();
                            // Show success message
                            msg = new Message(MessageConstants.I0001, MessageType.Info, "Danh mục '" + objUI.CategoryName + "'", "cập nhật");
                        //}                        
                    }
                }
            }
            catch (Exception)
            {
                // Show system error
                msg = new Message(MessageConstants.E0007, MessageType.Error);
            }

            return msg;
        }

        private bool CheckParentCatIsUsing(Category objUI)
        {
            bool result = false;

            if (objUI.ParentId != null)
            {
                Category parent = GetByID(objUI.ParentId.Value);
                if (parent.Partners.Where(c => c.DeleteFlag == false).Count<Partner>() > 0)
                {
                    result = true;
                }
            }

            return result;
        }

        public Message UpdateImage(Category objUI)
        {
            Message msg = null;
            try
            {
                if (objUI != null)
                {
                    Category objDb = GetByID(objUI.ID);

                    if (objDb != null)
                    {
                        objDb.Image = objUI.Image;
                        dbContext.SubmitChanges();

                        msg = new Message(MessageConstants.I0001, MessageType.Info, "hình", "cập nhật");

                    }
                }
            }
            catch
            {
                msg = new Message(MessageConstants.E0007, MessageType.Error);
            }
            return msg;
        }

        public Message DeleteList(string ids)
        {
            Message msg = null;
            DbTransaction trans = null;
            try
            {
                dbContext.Connection.Open();
                trans = dbContext.Connection.BeginTransaction();
                dbContext.Transaction = trans;

                if (!string.IsNullOrEmpty(ids))
                {
                    List<Category> list = new List<Category>();
                    ids = ids.TrimEnd(',');
                    int categoryID = 0;

                    string[] idArr = ids.Split(',');
                    int total = idArr.Count();
                    List<string> imageList = new List<string>();
                    foreach (string id in idArr)
                    {
                        bool isValid = Int32.TryParse(id, out categoryID);
                        Category category = GetByID(categoryID);
                        if (category != null)
                        {
                            imageList.Add(category.Image);
                            list.Add(category);
                        }
                        else
                        {
                            total--;
                        }
                    }
                    if (list.Count > 0)
                    {
                        dbContext.Categories.DeleteAllOnSubmit(list);
                        dbContext.SubmitChanges();
                        // Show succes message
                        msg = new Message(MessageConstants.I0001, MessageType.Info, total.ToString() + " danh mục", "xóa");
                        trans.Commit();

                        //Delete image
                        foreach (string img in imageList)
                        {
                            if (!string.IsNullOrEmpty(img) && img != Constants.NO_IMAGE)
                            {
                                string strPath = HttpContext.Current.Server.MapPath(Constants.PHOTO_PATH_ROOT_CATEGORY) + img;
                                //strPath += "\\" + image;
                                if (System.IO.File.Exists(strPath))
                                    System.IO.File.Delete(strPath);
                            }
                        }
                    }
                    else
                    {
                        trans.Rollback();
                    }
                }
            }
            catch (Exception)
            {
                if (trans != null) trans.Rollback();
                // Show system error
                msg = new Message(MessageConstants.E0006, MessageType.Error, "xóa", "danh mục này");                
            }
            return msg;
        }

        public List<Category> GetChildList()
        {
            return dbContext.Categories.Where(c => c.ParentId != null || (c.ParentId == null && c.Categories.Count == 0)).ToList<Category>();
        }

        public List<Category> GetParentAndChildList()
        {
            List<Category> parentList = GetParentList();
            List<Category> categoryList = new List<Category>();

            //append child list
            foreach (Category parent in parentList)
            {
                categoryList.Add(parent);

                List<Category> childList = GetChildListByParentId(parent.ID);
                foreach (Category child in childList)
                {
                    child.CategoryName = parent.CategoryName + " --> " + child.CategoryName;
                    categoryList.Add(child);
                }
            }
            return categoryList;
        }

        public string GetParentNameByChildId(int childId)
        {
            string result = string.Empty;
            Category parent = dbContext.Categories.Where(c => c.ID == childId).Select(c => c.Category1).FirstOrDefault<Category>();
            if (parent != null)
            {
                result = parent.CategoryName + "-->";
            }

            return result;
        }

        public int GetLastOrder()
        {
            int lastOrder = 1;
            try
            {
                lastOrder = dbContext.Categories.OrderByDescending(c => c.CategoryOrder).Select(c => c.CategoryOrder).FirstOrDefault<int>();
            }
            catch (Exception)
            {

            }
            return lastOrder;
        }

        public Message MoveCategoryDown(Category objUI)
        {
            Message msg = null;
            try
            {
                if (objUI != null)
                {
                    // Get current group in dbContext
                    Category objCurrent = objUI;
                    Category objNext = GetByOrder(objUI.CategoryOrder + 1, false);

                    if (objCurrent != null && objNext != null)
                    {
                        int currentOrder = objCurrent.CategoryOrder;
                        int nextOrder = objNext.CategoryOrder;
                        // Update info by objUI
                        objCurrent.CategoryOrder = nextOrder;
                        objNext.CategoryOrder = currentOrder;

                        // Submit changes to dbContext
                        dbContext.SubmitChanges();
                        // Show success message
                        msg = new Message(MessageConstants.I0001, MessageType.Info, "Danh mục ", "cập nhật thứ tự");

                    }
                    else
                    {
                        // Show system error
                        msg = new Message(MessageConstants.E0007, MessageType.Error);
                    }
                }
            }
            catch (Exception)
            {
                // Show system error
                msg = new Message(MessageConstants.E0007, MessageType.Error);
            }

            return msg;
        }

        public Message MoveCategoryUp(Category objUI)
        {
            Message msg = null;
            try
            {
                if (objUI != null)
                {
                    // Get current group in dbContext
                    Category objCurrent = objUI;
                    Category objPrevious = GetByOrder(objUI.CategoryOrder - 1, true);

                    if (objCurrent != null && objPrevious != null)
                    {
                        int currentOrder = objCurrent.CategoryOrder;
                        int previousOrder = objPrevious.CategoryOrder;
                        // Update info by objUI
                        objCurrent.CategoryOrder = previousOrder;
                        objPrevious.CategoryOrder = currentOrder;

                        // Submit changes to dbContext
                        dbContext.SubmitChanges();
                        // Show success message
                        msg = new Message(MessageConstants.I0001, MessageType.Info, "Danh mục ", "cập nhật thứ tự");

                    }
                    else
                    {
                        // Show system error
                        msg = new Message(MessageConstants.E0007, MessageType.Error);
                    }
                }
            }
            catch (Exception)
            {
                // Show system error
                msg = new Message(MessageConstants.E0007, MessageType.Error);
            }

            return msg;
        }

        public Category GetByOrder(int order, bool up)
        {            
            Category nextCat = dbContext.Categories.Where(c => c.CategoryOrder == order && !c.ParentId.HasValue).FirstOrDefault<Category>();
            if (nextCat == null)
            {
                List<Category> list = dbContext.Categories.Where(c => !c.ParentId.HasValue).ToList<Category>();
                while (nextCat == null && (up && order > 1) || (!up && order < GetLastOrder()))
                {
                    if (up)
                    {
                        order = order - 1;                        
                    }
                    else
                    {
                        order = order + 1;
                    }
                    nextCat = list.Where(c => c.CategoryOrder == order).FirstOrDefault<Category>();

                }
                //if (up)
                //{
                //    order = order - 1;
                //    //GetByOrder(order, true);
                //}
                //else
                //{
                //    order = order + 1;
                //    //GetByOrder(order, false);
                //}
            }            
            return nextCat;
        }
    }
}